#include "toDetFinAut.h"

toDetFinAut::toDetFinAut()
{
}

toDetFinAut::~toDetFinAut()
{
}

DetFinAut<char> toDetFinAut::convertToDetFinAut(NonFinAut<char> &NFA)
{
	list<Transition<char>> transitionList = NFA.getTransitionList();
	list<char> startList = NFA.getStartList();
	list<char> stateList = NFA.getStateList();
	list<char> finishList = NFA.getFinishList();
	list<char> symbolList = NFA.getSymbolList();
	DetFinAut<char> detFinAut;
	string tempState;
	NonFinAut<list<char>> nonFinAut = NonFinAut<list<char>>();
	list<list<char>> tempList;
	list<string> stringList;
	list<char> tempFinishList;
	char state = 'B';
	list<Transition<list<char>>> tempTransitionList;
	list<list<char>>::const_iterator i, m;
	list<char>::const_iterator j, k;
	list<Transition<char>>::const_iterator l;
	list<Transition<list<char>>>::const_iterator n;
	list<string>::const_iterator o, p;
	tempList.push_front(startList);
	for(j = startList.begin(); j != startList.end(); j++)
	{
		tempState += *j;
	}
	stringList.push_front(tempState + 'A');
	for(k = finishList.begin(); k != finishList.end(); k++)
	{
		if(tempState.find(*k) != string::npos)
		{
			tempFinishList.push_back('A');
		}
	}
	for(i = tempList.begin(); i != tempList.end(); i++)
	{
		for(j = symbolList.begin(); j != symbolList.end(); j++)
		{
			list<char> tempStateList;
			string stateA;
			bool exist = false;
			for(k = i->begin(); k != i->end(); k++)
			{
				for(l = transitionList.begin(); l != transitionList.end(); l++)
				{
					if(l->begin == *k && l->symbol == *j)
					{
						tempStateList.push_back(l->end);
					}
				}
			}
			tempStateList.sort();
			tempStateList.unique();
			if(tempStateList.empty())
			{
				tempStateList.push_front('!');
			}
			for(k = tempStateList.begin(); k != tempStateList.end(); k++)
			{
				stateA += *k;
			}
			for(m = tempList.begin(); m != tempList.end(); m++)
			{
				string stateB;
				for(k = m->begin(); k != m->end(); k++)
				{
					stateB += *k;
				}
				if(stateA == stateB)
				{
					exist = true;
					break;
				}
			}
			if(!exist)
			{
				stringList.push_back(stateA + state);
				for(k = finishList.begin(); k != finishList.end(); k++)
				{
					if(stateA.find(*k) != string::npos)
					{
						tempFinishList.push_back(state);
					}
				}
				state++;
				tempList.push_back(tempStateList);
			}
			nonFinAut.addTransition(*i, *j, tempStateList);
		}
	}
	tempFinishList.sort();
	tempFinishList.unique();
	detFinAut = DetFinAut<char>('A', tempFinishList);
	tempTransitionList = nonFinAut.getTransitionList();
	for(n = tempTransitionList.begin(); n != tempTransitionList.end(); n++)
	{
		string stateA, stateB;
		list<char> tempStateList = n->begin;
		for(j = tempStateList.begin(); j != tempStateList.end(); j++)
		{
			stateA += *j;
		}
		for(o = stringList.begin(); o != stringList.end(); o++)
		{
			if(o->compare(0, stateA.length(), stateA) == 0)
			{
				tempStateList = n->end;
				for(j = tempStateList.begin(); j != tempStateList.end(); j++)
				{
					stateB += *j;
				}
				for(p = stringList.begin(); p != stringList.end(); p++)
				{
					if(p->compare(0, stateB.length(), stateB) == 0)
					{
						detFinAut.addTransition((*o)[stateA.length()], n->symbol, (*p)[stateB.length()]);
						break;
					}
				}
			}
		}
	}
	return detFinAut;
}